<?php

Raise::load('core.RaiseObject');
Raise::load('core.session.IRaiseSessionStore');
Raise::load('core.io.file.RaisePath');
Raise::load('core.io.file.RaiseFile');
Raise::load('core.io.file.RaiseFileSystem');
Raise::load('core.security.RaiseHashDigest');

/**
 * RaiseSessionFileStore class
 * file storage for session store
 *
 * @author Sam-Mauris Yong / hellclanner at live dot com
 * @license http://www.opensource.org/licenses/bsd-license New BSD License
 * @package phpraise.core.session.store
 * @since 1.2
 */
class RaiseSessionFileStore extends RaiseObject implements IRaiseSessionStore {

    /**
     * The path name to the folder containing all the RaiseSession storage
     * @var string
     */
    private $folder;

    /**
     * The session name
     * @var string
     */
    private $sessionName;

    /**
     * The original working directory. This is to counter the "Current working directory is changed with some SAPIs if session is closed in the script termination. It is possible to close the session earlier with session_write_close(). "
     * problem as disclosed on the PHP manual
     * @var string
     */
    private $originalWorkingDir;

    /**
     * Create a new RaiseSessionFileStore
     * @param string $folder The folder to store all the session data
     */
    public function  __construct($folder) {
        $this->folder = $folder;
        $this->originalWorkingDir = getcwd();
    }

    public function close() {
        return true;
    }

    public function destroy($sessionId) {
        $path = RaisePath::combine($this->folder, $this->sessionName . '-' . $sessionId);
        $file = new RaiseFile($path);
        if($file->exists()){
            return $file->delete();
        }
    }

    public function garbageCollect($life) {
        if($this->originalWorkingDir){
            chdir($this->originalWorkingDir);
        }
        $files = RaiseFileSystem::pathSearch(RaisePath::combine($this->folder, $this->sessionName . '-*'));
        foreach($files as $f){
            $file = new RaiseFile($f);
            if($file->lastModified()->add(new RaiseTimeSpan($life))->toTimestamp() < time()){
                $file->delete();
            }
        }
    }

    public function open($path, $sessionName) {
        $this->sessionName = RaiseHashDigest::crc32($sessionName);
        return true;
    }

    public function read($sessionId) {
        if($this->originalWorkingDir){
            chdir($this->originalWorkingDir);
        }
        $path = RaisePath::combine($this->folder, $this->sessionName . '-' . $sessionId);
        $file = new RaiseFile($path);
        if($file->exists()){
            return $file->read();
        }
        return '';
    }

    public function write($sessionId, $data) {
        if($this->originalWorkingDir){
            chdir($this->originalWorkingDir);
        }
        $path = RaisePath::combine($this->folder, $this->sessionName . '-' . $sessionId);
        $file = new RaiseFile($path);
        $ok = false;
        $ok = $file->write($data);
        return $ok;
    }

    public function sessionExist($sessionId) {
        if($this->originalWorkingDir){
            chdir($this->originalWorkingDir);
        }
        $path = RaisePath::combine($this->folder, $this->sessionName . '-' . $sessionId);
        $file = new RaiseFile($path);
        return $file->exists();
    }

}
